#!/usr/bin/python

import logging
import os
import urllib
import re
import json
import SimpleHTTPServer
import SocketServer
import Postie

class UrlParser:
    def get_params(self, path):
        query_index = path.find("?")
        if query_index > -1:
            params = dict()
            key_value_pairs = path[query_index + 1:].split("&")
            for pair in key_value_pairs:
                val = pair.split("=")
                if len(val) == 1:
                    params[val[0]] = ""
                else:
                    params[val[0]] = urllib.unquote_plus(val[1])
            return params
        else:
            return dict()
    
    def get_resource(self, path):
        resource = path[1:]
        query_index = resource.find("?")
        if query_index > -1:
            resource = resource[:query_index]
        
        return resource

class StaticFileRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
    def __init__(self, request, client_address, server):
        SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
        self.__log = logging.getLogger("request-handler")
        print("RequestHandler created")

    def do_GET(self):
        if self.path.find("dynamic") == -1:
            SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
        else:
            parser = UrlParser()
            params = parser.get_params(self.path)
            resource = parser.get_resource(self.path)
            request_processor = StaticFileRequestHandler.config.get_request_processor(resource)
            try:
                request_processor.handle_request(params, resource)
    
                self.send_response(200)
                self.send_header("Content-Type", "application/json")
                self.end_headers()
                request_processor.write_response(self.wfile)
            except IOError as err:
                self.__log.warn("Unable to process request", err)


class RequestProcessor:
    def __init__(self):
        self.__log = logging.getLogger("request-processor")
    
    def handle_request(self, params, path):
        raise Exception("Subclasses should override handle_request")
    


class GetTipsRequestProcessor(RequestProcessor):
    def __init__(self, post_repository):
        self.__post_repository = post_repository
        
    def handle_request(self, params, path):
        return

    def write_response(self, output):
        output.write(json.dumps(self.__post_repository.load_all_posts(), cls = Postie.PostJsonEncoder))


class Config:
    def __init__(self, document_root, port):
        self.__document_root = document_root
        self.__port = port
        self.__request_processors = dict()
    
    def port(self):
        return self.__port
    
    def add_request_processor(self, path_regex, request_processor):
        self.__request_processors[path_regex] = request_processor
    
    def get_request_processor(self, path):
        for path_regex in self.__request_processors.keys():
            match = re.match(path_regex, path)
            if match is not None:
                return self.__request_processors[path_regex]
        raise RuntimeError("No RequestProcessor mapped to resource")

class Server:
    def __init__(self, config):
        self.__log = logging.getLogger("server")
        self.__config = config
    
    def start(self):
        port = self.__config.port()
        self.__log.info("Listening on port " + str(port))
        StaticFileRequestHandler.config = self.__config
        server = SocketServer.TCPServer(("", port), StaticFileRequestHandler)
        server.serve_forever()

if __name__ == "__main__":
    logging.basicConfig(level = logging.INFO)
    config = Config(os.path.expanduser("~/Documents/pyong_root"), 8000)
    config.add_request_processor(r"^dynamic/tips$", GetTipsRequestProcessor(Postie.PostRepository()))
    
    server = Server(config)
    server.start()
    
    

